package urjc.as.emergencies.client;

import java.io.IOException;

import org.restlet.Client;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Preference;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;

import urjc.as.emergencies.data.Ambulance;
import urjc.as.emergencies.data.BaseEntity;

/**
 * @author Sergio Saugar
 */
public class CommToolkit {

	// ///////// URIs
	private static final String SERVER = "http://localhost:8080";
	public static final String MISSIONS = SERVER + "/missions";
	public static final String MISSION = MISSIONS + "/" + "{idMission}";
	public static final String AMBULANCES = SERVER + "/ambulancias";
	
	/**
	 * Realiza una petición POST contra ambulancias para crear una nueva
	 * 
	 * @param ambulance
	 *            objeto que representa a la ambulancia
	 * @param targetURI
	 *            URI a la que reliazar la peticion POST
	 * @return la URI de la nueva localizacion del recurso
	 */
	public static Response createAmbulance(Ambulance ambulance, String targetURI) {

		// Creamos la petición como un método POST sobre targetURI
		Request request = new Request(Method.POST, targetURI);

		// Rellenamos el contenido del mensaje y marcamos su tipo de
		// representación
		request.setEntity(ambulance.serializar(), MediaType.TEXT_XML);

		// Realizamos la petición
		Response resp = CommToolkit.doRequest(request);

		return resp;
	}

	/**
	 * Solicita la representación en XML de una entidad
	 * 
	 * @param targetURI
	 *            La URI de la entidad
	 * @return Un objeto java obtenido mediante deserialización con JAXB o null
	 *         si error.
	 */
	public static Object getRepresentation(String targetURI) {

		// Creamos la petición como un método GET sobre targetURI
		Request request = new Request(Method.GET, targetURI);

		// Realizamos la petición
		Response resp = CommToolkit.doRequest(request);

		if (resp.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND))
			System.out.println("Error Cliente");

		
		Object obj = null;
		try {
			obj = BaseEntity.deserializar(resp.getEntity().getText());
		} catch (IOException ioe) {
			System.err
					.println("Exception -- Problem while extracting the content of the response.");
			ioe.printStackTrace(System.err);
		}
		return obj;
	}

	/**
	 * Realiza una peticion PATCH para actualizar la representacion de una
	 * ambulancia
	 * 
	 * @param targetURI
	 *            la URI sobre la que realizar el metodo PATCH
	 * @param clave
	 *            la clave del atributo que se desea cambiar
	 * @param valor
	 *            nuevo valor que se desea dar a la clave anterior
	 */
	public static Status actualizaRepresentacion(String targetURI, String clave,
			String valor) {
		// Creamos la petición como un método Patch sobre targetURI
		Request request = new Request(new Method("PATCH"), targetURI);
		 
		//Creamos un form para meter los nuevos valores
		Form form = new Form();
		form.add(clave, valor);
		request.setEntity(form.getWebRepresentation());
		
		// Realizamos la petición
		Response resp = CommToolkit.doRequest(request);

		
		if (resp.getStatus().equals(Status.CLIENT_ERROR_BAD_REQUEST)) {
			System.out.println("Error cliente");
		}
		return resp.getStatus();
	}
	
	public static Status sendPatch(String _uri, Form _form) {
		Request request = new Request(new Method("PATCH"), _uri);
		request.setEntity(_form.getWebRepresentation());
		Response resp = CommToolkit.doRequest(request);
		return resp.getStatus();
	}

	/**
	 * Realiza la solicitud HTTP y obtiene la respuesta del servidor
	 */
	public static Response doRequest(Request request) {

		// Creamos un conector cliente
		Client client = new Client(Protocol.HTTP);

		// Rellenamos los tipos de representación que acepta nuestro cliente, de
		// cara a la negociación con el servidor
		request.getClientInfo().getAcceptedMediaTypes().add(
				new Preference<MediaType>(MediaType.TEXT_XML));

		// Realizamos la solicitud y obtenemos una respuesta
		Response response = client.handle(request);
		System.out.println(response.getStatus().getDescription());
		return response;
	}
	
	/**
	 * Manda una petición PUT con el objeto que se re
	 * @param ob
	 * @return
	 */
	public static Response doPut(BaseEntity ob) {
		Request request = new Request(Method.PUT, ob.getUri());
		request.setEntity(ob.serializar(), MediaType.TEXT_XML);
		return doRequest(request);
	}
	
	/**
	 * 
	 * @param ob
	 * @return
	 */
	public static Response sendDelete(BaseEntity ob){
		Request request =  new Request(Method.DELETE, ob.getUri());
		request.setEntity(ob.serializar(), MediaType.TEXT_XML);
		return doRequest(request);
	}
}
